package cqrtplm.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.pdm.ec.module.vo.ChgFormVO;
import com.hustcad.plm.pdm.ec.module.vo.ECObjDataVO;
import com.hustcad.plm.pdm.ec.service.TyChangeExtService;
import com.hustcad.plm.pdm.ec.service.TyplmChgNoticeService;
import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.partbom.vo.PartDetailsVO;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.part.PartDO;
import com.ty.security.util.TyCommonUtils;
import com.ty.security.util.TyJsonDataUtil;
import cqrtplm.common.CommonService;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.entity.RtChangeaffectAssociatedbomDO;
import cqrtplm.mapper.RTChangeMapper;
import cqrtplm.mapper.RtCertFiledMapper;
import cqrtplm.mapper.RtChangeaffectAssociatedbomMapper;
import cqrtplm.service.BOMCertificationService;
import cqrtplm.vo.RtCertFiledVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class BOMCertificationServiceImpl implements BOMCertificationService {

    @Resource
    private TyplmPartService typlmPartService;

    @Resource
    private CommonService commonService;

    @Resource
    private RTChangeMapper rtChangeMapper;

    @Resource
    private RtCertFiledMapper rtCertFiledMapper;
    @Resource
    private TyplmPdmPartService typlmPdmPartService;
    @Resource
    private TyChangeExtService tyChangeExtService;
    @Resource
    private TyplmChgNoticeService typlmChgNoticeService;
    @Resource
    private RtChangeaffectAssociatedbomMapper rtChangeaffectAssociatedbomMapper;

    @Override
    public void validateBOMCertification(JSONObject req) throws Exception {
        List<String> errorList = new ArrayList<>();
        if (!ObjectUtils.isEmpty(req)) {
            JSONObject jsonObject = TyJsonDataUtil.toJSON(req);
            JSONObject entityJson = jsonObject.getJSONObject("entity");
            IdentifierEntity entity = (IdentifierEntity) entityJson.toJavaObject(IdentifierEntity.class);
            List<ECObjDataVO> ecObjDTOS = ((JSONArray) TyCommonUtils.requireNonNull(jsonObject.getJSONArray("relentity"), "relentity")).toJavaList(ECObjDataVO.class);
            // ChgNoticeDO noticeDO=typlmChgNoticeService.selectByPrimaryKey(entity.getOid());
            ChgFormVO chgFormVO = this.tyChangeExtService.getChgFormByEcnOid(entity);
            String formData = chgFormVO.getFormData();
            for (ECObjDataVO dataVO : ecObjDTOS) {
                BigInteger oid = dataVO.getOid();
                String otype = dataVO.getOtype();
                String changeNo = chgFormVO.getObjectNumber();
                // 查询BOM树
                // TyPartAllVO tyPartAllVO = typlmPartService.queryPartAllVO(oid, otype);
                PartDetailsVO parentDetailsVO = typlmPartService.queryPartDetails(oid, otype);
                String type = parentDetailsVO.getTypeName();
                if ("成品码".equals(type)||"EBOM号".equals(type)) {
                    String parentNumber = parentDetailsVO.getObjectNumber();
                    //获取关联变更影响的成品BOM
                    List<RtChangeaffectAssociatedbomDO> associatedbomDOS = rtChangeaffectAssociatedbomMapper.queryByChangeNoAndPartNo(changeNo, "");
                    List<PartDO> clearChildParts = new ArrayList<>();
                    if (CollectionUtils.isNotEmpty(associatedbomDOS)) {
                        associatedbomDOS.forEach(associatedbomDO -> {
                            String bomType = associatedbomDO.getBomtype();
                            String partNumber = associatedbomDO.getPartnumber();
                            String productCode = associatedbomDO.getCode();
                            String materialCode = associatedbomDO.getMaterialCode();
                            String parttype = associatedbomDO.getParttype();
                            if ("成品码".equals(bomType)) {
                                if (parentNumber.equals(productCode)) {
                                    if (StringUtils.isNotBlank(formData)) {
                                        JSONObject formDataJson = JSONObject.parseObject(formData);
                                        JSONArray subform57714 = formDataJson.getJSONArray("subform57714");
                                        if (CollectionUtils.isNotEmpty(subform57714)) {
                                            for (int i = 0; i < subform57714.size(); i++) {
                                                String beforeChangeNo = subform57714.getJSONObject(i).getString("input36063");
                                                String changeType = subform57714.getJSONObject(i).getString("input70284");
                                                String afterChangeNo = subform57714.getJSONObject(i).getString("input37516");
                                                if ("增加".equals(changeType)) {
                                                    if (partNumber.equals(afterChangeNo)) {
                                                        String afterMaterialcode ="";
                                                        if ("PatternCode".equals(parttype)) {
                                                            String colorCode = "";
                                                            if ("H".equals(materialCode.charAt(5))) {
                                                                colorCode = materialCode.split("-")[1];
                                                            } else {
                                                                colorCode = materialCode.split("-")[2];
                                                            }
                                                            if (StringUtils.isNotBlank(materialCode)) {
                                                                afterMaterialcode = afterChangeNo + "-" + colorCode;
                                                            }
                                                        }else{
                                                            afterMaterialcode = afterChangeNo;
                                                        }
                                                        List<JSONObject> list = this.rtChangeMapper.queryPatternOrMaterialCode(afterMaterialcode, "MaterialCode", RTPlmConstant.VIEW_DESIGN);
                                                        if (CollectionUtils.isNotEmpty(list)) {
                                                            JSONObject jsonObject1 = list.get(0);
                                                            String oid1 = jsonObject1.getString("OID");
                                                            String otype1 = jsonObject1.getString("OTYPE");
                                                            PartDO partDO = this.typlmPartService.queryPartByOid(new BigInteger(oid1), otype1);
                                                            clearChildParts.add(partDO);
                                                        }
                                                    }
                                                } else if ("替换".equals(changeType) || "修改".equals(changeType)) {
                                                    if (partNumber.equals(beforeChangeNo)) {
                                                        String afterMaterialcode ="";
                                                        if ("PatternCode".equals(parttype)) {
                                                            String colorCode = "";
                                                            if ("H".equals(materialCode.charAt(5))) {
                                                                colorCode = materialCode.split("-")[1];
                                                            } else {
                                                                colorCode = materialCode.split("-")[2];
                                                            }
                                                            if (org.apache.commons.lang.StringUtils.isNotBlank(materialCode)) {
                                                                afterMaterialcode = afterChangeNo + "-" + colorCode;
                                                            }
                                                        }else{
                                                            afterMaterialcode = afterChangeNo;
                                                        }
                                                        List<JSONObject> list = this.rtChangeMapper.queryPatternOrMaterialCode(afterMaterialcode, "MaterialCode", RTPlmConstant.VIEW_DESIGN);
                                                        if (CollectionUtils.isNotEmpty(list)) {
                                                            JSONObject jsonObject1 = list.get(0);
                                                            String oid1 = jsonObject1.getString("OID");
                                                            String otype1 = jsonObject1.getString("OTYPE");
                                                            PartDO partDO = this.typlmPartService.queryPartByOid(new BigInteger(oid1), otype1);
                                                            clearChildParts.add(partDO);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }else if ("EBOM号".equals(bomType)) {
                                if (parentNumber.equals(productCode)) {
                                    if (StringUtils.isNotBlank(formData)) {
                                        JSONObject formDataJson = JSONObject.parseObject(formData);
                                        JSONArray subform57714 = formDataJson.getJSONArray("subform57714");
                                        if (CollectionUtils.isNotEmpty(subform57714)) {
                                            for (int i = 0; i < subform57714.size(); i++) {
                                                String beforeChangeNo = subform57714.getJSONObject(i).getString("input36063");
                                                String changeType = subform57714.getJSONObject(i).getString("input70284");
                                                String afterChangeNo = subform57714.getJSONObject(i).getString("input37516");
                                                if ("增加".equals(changeType)) {
                                                    if (partNumber.equals(afterChangeNo)) {
                                                        List<JSONObject> list = this.rtChangeMapper.queryPatternOrMaterialCode(afterChangeNo, "PatternCode", RTPlmConstant.VIEW_DESIGN);
                                                        if (CollectionUtils.isNotEmpty(list)) {
                                                            JSONObject jsonObject1 = list.get(0);
                                                            String oid1 = jsonObject1.getString("OID");
                                                            String otype1 = jsonObject1.getString("OTYPE");
                                                            PartDO partDO = this.typlmPartService.queryPartByOid(new BigInteger(oid1), otype1);
                                                            clearChildParts.add(partDO);
                                                        }
                                                    }
                                                } else if ("替换".equals(changeType) || "修改".equals(changeType)) {
                                                    if (partNumber.equals(beforeChangeNo)) {
                                                        List<JSONObject> list = this.rtChangeMapper.queryPatternOrMaterialCode(beforeChangeNo, "PatternCode", RTPlmConstant.VIEW_DESIGN);
                                                        if (CollectionUtils.isNotEmpty(list)) {
                                                            JSONObject jsonObject1 = list.get(0);
                                                            String oid1 = jsonObject1.getString("OID");
                                                            String otype1 = jsonObject1.getString("OTYPE");
                                                            PartDO partDO = this.typlmPartService.queryPartByOid(new BigInteger(oid1), otype1);
                                                            clearChildParts.add(partDO);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        });
                    }
                    // 根据Oid查询子件
//                    List<PartDO> childParts = rtChangeMapper.queryChildPart(String.valueOf(oid),
//                                                                            RTPlmConstant.VIEW_DESIGN);
//
//                    if (childParts != null) {
//                        for (PartDO partDO : childParts) {
//                            PartDetailsVO detailsVO = this.typlmPdmPartService.queryPartDetailsForCO(partDO.getOid(),
//                                                                                                     partDO.getOtype());
//                            if (!"成品码".equals(detailsVO.getTypeName())) {
//                                clearChildParts.add(partDO);
//                            }
//                        }
//                    }
                    //认证要求
                    String certificationRequire = rtChangeMapper.queryIBAValueByOidAndOtype(String.valueOf(oid), otype, "CertificationRequire");
                    //动力备案机型
                    String PowerRegistrationModel = rtChangeMapper.queryIBAValueByOidAndOtype(String.valueOf(oid), otype, "PowerRegistrationModel");
                    //客户代码
                    String CustomerCode = rtChangeMapper.queryIBAValueByOidAndOtype(String.valueOf(oid), otype, "CustomerCode");
                    //此数据已经写死，为了方便测试使用，正常使用请注释掉这行代码
//                    certificationRequire = "国II+EU5+EPA+PGMA";
                    Map<String, List<PartDO>> resultMap = traverseAndValidateCertification(clearChildParts);
                    String certVerificatyType = RTPlmConstant.certVerificatyType;
                    List<String> coerceCertList = Arrays.asList(certVerificatyType.split(","));
                    // 拆分认证要求
                    List<String> certificationList = new ArrayList<>();
                    if (StringUtils.isNotBlank(certificationRequire) && !certificationRequire.equals("无认证")) {
                        String[] certs = certificationRequire.replaceAll(";","+").split("\\+");
                        for (String cert : certs) {
                            if (!cert.isEmpty()) {
                                if (coerceCertList.contains(cert)) {
                                    certificationList.add(cert);
                                }
                            }
                        }
                    }
//                    PowerRegistrationModel = "R100";
                    if (StringUtils.isNotBlank(PowerRegistrationModel) && CollUtil.isNotEmpty(certificationList)) {
                        // 查询认证信息
                        List<RtCertFiledVO> certInfoList = rtCertFiledMapper.queryCertByCtypeAndModel(certificationList, PowerRegistrationModel);
                        // 7. 比较并验证认证
                        errorList = comparePartCodeAndPatternCode(parentDetailsVO, PowerRegistrationModel, resultMap, certInfoList, certificationList, errorList);
                    }
                    //如果没有认证，抛出异常
                    if (CollUtil.isNotEmpty(errorList)) {
                        StringBuffer errMsg = new StringBuffer();
                        for (String error : errorList) {
                            errMsg.append(error + "\n");
                        }
                        throw new Exception(errMsg.toString());
                    }
                }
            }
        }
    }


    private List<String> comparePartCodeAndPatternCode(PartDetailsVO parentDetailsVO, String PowerRegistrationModel, Map<String, List<PartDO>> bomMap, List<RtCertFiledVO> certInfoList, List<String> certificationList, List<String> errorList) {
        // 错误信息
        String error = "";
        // 遍历验证每个部件是否备案
        for (String partCode : bomMap.keySet()) {
            List<PartDO> patternList = bomMap.get(partCode);
            List<RtCertFiledVO> tempList = new ArrayList<>();
            // 获取当前partCode对应的认证信息
            if (certInfoList.size() > 0) {
                tempList = certInfoList.stream().filter(item -> item.getPartCode().equals(partCode)).collect(Collectors.toList());
            }
            if ("18100".equals(partCode)) {
                //消声器部件检查逻辑
                for (PartDO partDO : patternList) {
                    String partNumber = partDO.getPartnumber();
                    String patternCode = partNumber.substring(0, 11);
                    //当18100无备案
                    for (int j = 0; j < certificationList.size(); j++) {
                        String cert = certificationList.get(j);
                        int index = 0;
                        for (int i = 0; i < tempList.size(); i++) {
                            RtCertFiledVO filedVO = tempList.get(i);
                            String tempNo = filedVO.getPartNo();
                            String tempType = filedVO.getCType();
                            if (!tempNo.equals(patternCode) || !cert.equals(tempType)) {
                                index++;
                            }
                        }
                        if (index == tempList.size()) {
                            //根据18100物料料描述获取18160图号
                            PartDetailsVO detailsVO = this.typlmPdmPartService.queryPartDetailsForCO(partDO.getOid(), partDO.getOtype());
                            Map<String,List<String>> ibaMap=detailsVO.getIbaAttributeMap();
                            String desc = ibaMap.containsKey(RTPlmConstant.IBA_MATERIALCODEDESCRIPTION)?ibaMap.get(RTPlmConstant.IBA_MATERIALCODEDESCRIPTION).get(0):"";
                            if (StringUtils.isNotBlank(desc) && desc.contains("消声器体打刻")) {
                                String tempNumber = desc.substring(desc.indexOf("消声器体打刻"), desc.indexOf("消声器体打刻") + 6 + 11);
                                //获取18160的备案零部件数据
                                List<RtCertFiledVO> filterCertVOS = certInfoList.stream().filter(item -> "18160".equals(item.getPartCode())).collect(Collectors.toList());
                                //检查消声器体的是否备案
                                for (int k = 0; k < certificationList.size(); k++) {
                                    String cert2 = certificationList.get(k);
                                    int index2 = 0;
                                    for (int i = 0; i < filterCertVOS.size(); i++) {
                                        RtCertFiledVO filedVO = filterCertVOS.get(i);
                                        String tempNo = filedVO.getPartNo();
                                        String tempType = filedVO.getCType();
                                        if (!tempNo.equals(tempNumber) || !cert2.equals(tempType)) {
                                            index2++;
                                        }
                                    }
                                    if (index2 == filterCertVOS.size()) {
                                        errorList.add("备案机型为" + PowerRegistrationModel + "的成品码" + parentDetailsVO.getObjectNumber() + "下的" + tempNumber + "未在" + cert2 + "认证里面备案，请处理!");
                                    }
                                }
                            } else {
                                errorList.add("备案机型为" + PowerRegistrationModel + "的成品码" + parentDetailsVO.getObjectNumber() + "下的" + partNumber + "未在" + cert + "认证里面备案，请处理!");
                            }
                        }
                    }
                }
            } else {
                //其它
                for (PartDO partDO : patternList) {
                    String partNumber = partDO.getPartnumber();
                    String patternCode = partNumber.substring(0, 11);
                    for (int j = 0; j < certificationList.size(); j++) {
                        String cert = certificationList.get(j);
                        int index = 0;
                        for (int i = 0; i < tempList.size(); i++) {
                            RtCertFiledVO filedVO = tempList.get(i);
                            String tempNo = filedVO.getPartNo();
                            String tempType = filedVO.getCType();
                            if (!tempNo.equals(patternCode) || !cert.equals(tempType)) {
                                index++;
                            }
                        }
                        if (index == tempList.size()) {
                            errorList.add("备案机型为" + PowerRegistrationModel + "的成品码" + parentDetailsVO.getObjectNumber() + "下的" + partNumber + "未在" + cert + "认证里面备案，请处理!");
                        }
                    }
                }
            }
        }
        return errorList;
    }

    private Map<String, List<PartDO>> traverseAndValidateCertification(List<PartDO> partBomTreeList) {
        Map<String, List<PartDO>> resultMap = new HashMap<String, List<PartDO>>();
        for (PartDO partDO : partBomTreeList) {
            // 获取对象编号
            String objectNumber = partDO.getPartnumber();
            // 先匹配前五位
            String partCode = objectNumber.substring(0, 5);
            List<PartDO> patternList = null;
            if (resultMap.containsKey(partCode)) {
                patternList = resultMap.get(partCode);
                if (!patternList.contains(partDO)) {
                    patternList.add(partDO);
                }
            } else {
                patternList = new ArrayList<>();
                patternList.add(partDO);
            }
            resultMap.put(partCode, patternList);
        }
        return resultMap;
    }

    /**
     * 检查部件是否被认证
     */
    private boolean isPartCertified(String patternCode, List<RtCertFiledVO> tempList) {
        if (CollUtil.isEmpty(tempList)) {
            return false;
        }
        for (RtCertFiledVO rtCertFiledVO : tempList) {
            if (patternCode.equals(rtCertFiledVO.getPartNo())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取认证类型
     */
    private String getCertType(List<RtCertFiledVO> tempList) {
        return CollUtil.isNotEmpty(tempList) ? tempList.get(0).getCType() : "未知";
    }
}

